﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using HYElectricKernel;
using HYRElectric.WirePlace;

namespace HYRElectric.Equipment
{
	public class RectLayoutEx : EquipmentLayout
	{
		public RectLayoutEx(UIDocument uiDoc, Document document, DbFamilyObject familyObject, FamilySymbol selectedFamilySymbol, List<BuiltInCategory> lstFilter) : base(uiDoc, document, familyObject, selectedFamilySymbol, lstFilter)
		{
		}

		public override bool Layout()
		{
			if (!base.Layout())
			{
				return false;
			}
			this.form = new RectLayoutExForm(this.doc);
			this.form.Show(WindowHelper.HWndRevit);
			WindowHelper.SendMessageToWndRevit();
			for (;;)
			{
				try
				{
					this.basePoint = this.docUI.Selection.PickPoint("请选取一点");
					LayoutEquipmentJig layoutEquipmentJig = new LayoutEquipmentJig(this.docUI, this.form);
					this.diagonalPoint = layoutEquipmentJig.PickEndPoint(this.basePoint, LayoutEquipmentJig.ELayoutType.eRectEx, "请选取对角点");
					layoutEquipmentJig.Dispose();
					if (this.diagonalPoint == null)
					{
						break;
					}
					if ((this.diagonalPoint - this.basePoint).IsZeroLength())
					{
						TaskDialog.Show("盈建科提示", "选取的两点为同一点，请选取两个不同点。");
						continue;
					}
				}
				catch (Exception)
				{
					break;
				}
				List<List<XYZ>> insertPoints = this.GetInsertPoints();
				if (!this.IsEmptyPointSet(insertPoints))
				{
					double angle = Convert.ToDouble(this.form.Angle);
					TransactionGroup transactionGroup = new TransactionGroup(this.doc, "TransactionGroup");
					try
					{
						transactionGroup.Start();
						Transaction transaction = null;
						try
						{
							foreach (List<XYZ> list in insertPoints)
							{
								FamilyInstance startdevice = null;
								foreach (XYZ xyz in list)
								{
									transaction = new Transaction(this.doc, "RectLayoutEx");
									transaction.Start();
									FamilyInstance familyInstance = YJKRevitTools.LayFamilySymbol(this.doc, xyz, this.familySymbol, this.doc.ActiveView.GenLevel, angle);
									if (familyInstance == null)
									{
										throw new Exception("布置设备出错。");
									}
									base.SetParametersValue(familyInstance, this.dbFamilyObject.Size);
									transaction.Commit();
									if (this.form.LinkLineWay != 0)
									{
                                        NewConnectWire.CreateWire(this.doc, startdevice, familyInstance, (Autodesk.Revit.DB.Electrical.WiringType)this.form.WireStyle, null);
										startdevice = familyInstance;
									}
								}
							}
						}
						catch (Exception)
						{
                            if (transaction != null && transaction.GetStatus() != TransactionStatus.Committed)
							{
								transaction.RollBack();
							}
							break;
						}
						transactionGroup.Assimilate();
						continue;
					}
					catch (Exception)
					{
						transactionGroup.RollBack();
						continue;
					}
					break;
				}
			}
			this.form.Close();
			return true;
		}

		private bool IsEmptyPointSet(List<List<XYZ>> pointSet)
		{
			if (pointSet == null || pointSet.Count <= 0)
			{
				return true;
			}
			foreach (List<XYZ> list in pointSet)
			{
				if (list != null && list.Count > 0)
				{
					return false;
				}
			}
			return true;
		}

		private List<List<XYZ>> GetInsertPoints()
		{
			if (this.form == null)
			{
				return null;
			}
			List<List<XYZ>> list = new List<List<XYZ>>();
			this.rowCount = this.form.RowCount;
			this.colCount = this.form.ColCount;
			this.margin = this.form.Margin;
			int rowAngle = this.form.RowAngle;
			if (this.rowCount <= 0 || this.colCount <= 0)
			{
				return null;
			}
			if (this.rowCount == 1 && this.colCount == 1)
			{
				List<XYZ> list2 = new List<XYZ>();
				XYZ item = this.basePoint + 0.5 * (this.diagonalPoint - this.basePoint);
				list2.Add(item);
				list.Add(list2);
				return list;
			}
			double num = AssistFunc.AngleToRadian((double)rowAngle);
			XYZ xyz = Geometry.RotateTo(this.diagonalPoint, this.basePoint, XYZ.BasisZ, -num);
			this.xDiagonalPoint = new XYZ(xyz.X, this.basePoint.Y, xyz.Z);
			this.yDiagonalPoint = new XYZ(this.basePoint.X, xyz.Y, xyz.Z);
			double num2 = this.basePoint.DistanceTo(this.xDiagonalPoint);
			double num3 = this.basePoint.DistanceTo(this.yDiagonalPoint);
			this.xSpace = ((Math.Abs(2.0 * this.margin + (double)this.colCount - 1.0) < 1E-06) ? 0.0 : (num2 / (2.0 * this.margin + (double)this.colCount - 1.0)));
			this.ySpace = ((Math.Abs(2.0 * this.margin + (double)this.rowCount - 1.0) < 1E-06) ? 0.0 : (num3 / (2.0 * this.margin + (double)this.rowCount - 1.0)));
			if (this.form.DislocationWay == 2)
			{
				list = this.GetInsertPointsOfCol();
			}
			else if (this.form.DislocationWay == 1)
			{
				list = this.GetInsertPointsOfRow();
			}
			else
			{
				list = this.GetInsertPointsOfNone();
			}
			foreach (List<XYZ> list3 in list)
			{
				for (int i = 0; i < list3.Count; i++)
				{
					XYZ pt = list3[i];
					list3[i] = Geometry.RotateTo(pt, this.basePoint, XYZ.BasisZ, num);
				}
			}
			return list;
		}

		private List<List<XYZ>> GetInsertPointsOfNone()
		{
			List<List<XYZ>> list = new List<List<XYZ>>();
			if (this.form.LinkLineWay == 2)
			{
				for (int i = 0; i < this.colCount; i++)
				{
					List<XYZ> list2 = new List<XYZ>();
					XYZ xyz = this.basePoint + this.xSpace * (this.margin + (double)i) * (this.xDiagonalPoint - this.basePoint).Normalize();
					for (int j = 0; j < this.rowCount; j++)
					{
						XYZ item = xyz + this.ySpace * (this.margin + (double)j) * (this.yDiagonalPoint - this.basePoint).Normalize();
						list2.Add(item);
					}
					list.Add(list2);
				}
			}
			else
			{
				for (int k = 0; k < this.rowCount; k++)
				{
					List<XYZ> list3 = new List<XYZ>();
					XYZ xyz2 = this.basePoint + this.ySpace * (this.margin + (double)k) * (this.yDiagonalPoint - this.basePoint).Normalize();
					for (int l = 0; l < this.colCount; l++)
					{
						XYZ item2 = xyz2 + this.xSpace * (this.margin + (double)l) * (this.xDiagonalPoint - this.basePoint).Normalize();
						list3.Add(item2);
					}
					list.Add(list3);
				}
			}
			return list;
		}

		private List<List<XYZ>> GetInsertPointsOfRow()
		{
			List<List<XYZ>> list = new List<List<XYZ>>();
			if (this.form.LinkLineWay == 2)
			{
				for (int i = 0; i < this.colCount; i++)
				{
					List<XYZ> list2 = new List<XYZ>();
					XYZ xyz = this.basePoint + this.xSpace * (this.margin + (double)i) * (this.xDiagonalPoint - this.basePoint).Normalize();
					for (int j = 0; j < this.rowCount; j += 2)
					{
						XYZ item = xyz + this.ySpace * (this.margin + (double)j) * (this.yDiagonalPoint - this.basePoint).Normalize();
						list2.Add(item);
					}
					list.Add(list2);
				}
				for (int k = 0; k < this.colCount - 1; k++)
				{
					List<XYZ> list3 = new List<XYZ>();
					XYZ xyz2 = this.basePoint + this.xSpace * (this.margin + 0.5 + (double)k) * (this.xDiagonalPoint - this.basePoint).Normalize();
					for (int l = 1; l < this.rowCount; l += 2)
					{
						XYZ item2 = xyz2 + this.ySpace * (this.margin + (double)l) * (this.yDiagonalPoint - this.basePoint).Normalize();
						list3.Add(item2);
					}
					list.Add(list3);
				}
			}
			else
			{
				for (int m = 0; m < this.rowCount; m += 2)
				{
					List<XYZ> list4 = new List<XYZ>();
					XYZ xyz3 = this.basePoint + this.ySpace * (this.margin + (double)m) * (this.yDiagonalPoint - this.basePoint).Normalize();
					for (int n = 0; n < this.colCount; n++)
					{
						XYZ item3 = xyz3 + this.xSpace * (this.margin + (double)n) * (this.xDiagonalPoint - this.basePoint).Normalize();
						list4.Add(item3);
					}
					list.Add(list4);
				}
				for (int num = 1; num < this.rowCount; num += 2)
				{
					List<XYZ> list5 = new List<XYZ>();
					XYZ xyz4 = this.basePoint + this.ySpace * (this.margin + (double)num) * (this.yDiagonalPoint - this.basePoint).Normalize();
					for (int num2 = 0; num2 < this.colCount - 1; num2++)
					{
						XYZ item4 = xyz4 + this.xSpace * (this.margin + 0.5 + (double)num2) * (this.xDiagonalPoint - this.basePoint).Normalize();
						list5.Add(item4);
					}
					list.Add(list5);
				}
			}
			return list;
		}

		private List<List<XYZ>> GetInsertPointsOfCol()
		{
			List<List<XYZ>> list = new List<List<XYZ>>();
			if (this.form.LinkLineWay == 2)
			{
				for (int i = 0; i < this.colCount; i += 2)
				{
					List<XYZ> list2 = new List<XYZ>();
					XYZ xyz = this.basePoint + this.xSpace * (this.margin + (double)i) * (this.xDiagonalPoint - this.basePoint).Normalize();
					for (int j = 0; j < this.rowCount; j++)
					{
						XYZ item = xyz + this.ySpace * (this.margin + (double)j) * (this.yDiagonalPoint - this.basePoint).Normalize();
						list2.Add(item);
					}
					list.Add(list2);
				}
				for (int k = 1; k < this.colCount; k += 2)
				{
					List<XYZ> list3 = new List<XYZ>();
					XYZ xyz2 = this.basePoint + this.xSpace * (this.margin + (double)k) * (this.xDiagonalPoint - this.basePoint).Normalize();
					for (int l = 0; l < this.rowCount - 1; l++)
					{
						XYZ item2 = xyz2 + this.ySpace * (this.margin + 0.5 + (double)l) * (this.yDiagonalPoint - this.basePoint).Normalize();
						list3.Add(item2);
					}
					list.Add(list3);
				}
			}
			else
			{
				for (int m = 0; m < this.rowCount; m++)
				{
					List<XYZ> list4 = new List<XYZ>();
					XYZ xyz3 = this.basePoint + this.ySpace * (this.margin + (double)m) * (this.yDiagonalPoint - this.basePoint).Normalize();
					for (int n = 0; n < this.colCount; n += 2)
					{
						XYZ item3 = xyz3 + this.xSpace * (this.margin + (double)n) * (this.xDiagonalPoint - this.basePoint).Normalize();
						list4.Add(item3);
					}
					list.Add(list4);
				}
				for (int num = 0; num < this.rowCount - 1; num++)
				{
					List<XYZ> list5 = new List<XYZ>();
					XYZ xyz4 = this.basePoint + this.ySpace * (this.margin + 0.5 + (double)num) * (this.yDiagonalPoint - this.basePoint).Normalize();
					for (int num2 = 1; num2 < this.colCount; num2 += 2)
					{
						XYZ item4 = xyz4 + this.xSpace * (this.margin + (double)num2) * (this.xDiagonalPoint - this.basePoint).Normalize();
						list5.Add(item4);
					}
					list.Add(list5);
				}
			}
			return list;
		}

		private RectLayoutExForm form;

		private XYZ basePoint;

		private XYZ diagonalPoint;

		private int rowCount;

		private int colCount;

		private double margin;

		private XYZ xDiagonalPoint = XYZ.Zero;

		private XYZ yDiagonalPoint = XYZ.Zero;

		private double xSpace;

		private double ySpace;
	}
}
